﻿/*
 * This file is part of MonoStrategy.
 *
 * Copyright (C) 2010-2011 Christoph Husse
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: 
 *      # Christoph Husse
 * 
 * Also checkout our homepage: http://monostrategy.codeplex.com/
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using OpenTK;
using OpenTK.Input;

using System.Runtime.InteropServices;

#if EMBEDDED
    using OpenTK.Graphics.ES20;
#else
using OpenTK.Graphics.OpenGL;
#endif

namespace MonoStrategy.RenderSystem
{
    internal class RegisteredImage
    {
        public System.Drawing.Bitmap Image { get; set; }
        public NativeTexture Texture { get; set; }
    }

    public partial class GLRenderer 
    {
        public void DrawSprite(Double inX, Double inY, Double inWidth, Double inHeight, int inImageID, Double inOpacity)
        {
            var image = m_RegisteredImages[inImageID];

            if (image.Texture == null)
                image.Texture = new NativeTexture(image.Image);

            image.Texture.Bind();

            DrawSpriteZAtlas(
                (float)inX, 
                (float)inY,
                (float)inWidth, 
                (float)inHeight, 
                (byte)255, (byte)255, (byte)255, 
                (byte)(255 * inOpacity), 
                0, 0, 1, 1);
        }

        public void DrawSpriteAtlas(Double inX, Double inY, Double inWidth, Double inHeight, int inImageID, Double inOpacity, int inTexX, int inTexY, int inTexWidth, int inTexHeight)
        {
            var image = m_RegisteredImages[inImageID];

            if (image.Texture == null)
                image.Texture = new NativeTexture(image.Image);

            image.Texture.Bind();

            double texScaleX = 1.0 / image.Image.Width;
            double texScaleY = 1.0 / image.Image.Height;

            DrawSpriteZAtlas(
                (float)inX,
                (float)inY,
                (float)inWidth,
                (float)inHeight,
                (byte)255, (byte)255, (byte)255,
                (byte)(255 * inOpacity),
                (float)(inTexX * texScaleX),
                (float)(inTexY * texScaleY), 
                (float)((inTexX + inTexWidth) * texScaleX),
                (float)((inTexY + inTexHeight) * texScaleY));
        }

        public void RegisterImage(int inImageID, System.Drawing.Bitmap inImage)
        {
            if (inImageID < 0)
                throw new ArgumentOutOfRangeException();

            if (inImage == null)
                throw new ArgumentNullException();

            while (m_RegisteredImages.Count <= inImageID)
            {
                m_RegisteredImages.Add(null);
            }

            if (m_RegisteredImages[inImageID] == null)
                m_RegisteredImages[inImageID] = new RegisteredImage(){Image = inImage};
        }

        internal void DrawSpriteZAtlas(float inLeft, float inTop, float inWidth, float inHeight, byte inRed, byte inGreen, byte inBlue, byte inAlpha, float inTexX1, float inTexY1, float inTexX2, float inTexY2)
        {
            GL.Begin(BeginMode.Quads);
            {
                GL.Color4(inRed, inGreen, inBlue, inAlpha);

                GL.TexCoord2(inTexX1, inTexY1);
                GL.Vertex3(inLeft, inTop, 0);
                GL.TexCoord2(inTexX2, inTexY1);
                GL.Vertex3(inLeft + inWidth, inTop, 0);
                GL.TexCoord2(inTexX2, inTexY2);
                GL.Vertex3(inLeft + inWidth, inTop + inHeight, 0);
                GL.TexCoord2(inTexX1, inTexY2);
                GL.Vertex3(inLeft, inTop + inHeight, 0);
            }
            GL.End();
        }
    }
}
